package com.softsec.isc.main;

import java.util.ArrayList;
import java.util.List;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.softsec.isc.analysis.DexMapItemMapper;
import com.softsec.isc.analysis.GetSpecialString;
import com.softsec.isc.apkextract.FileAction;
import com.softsec.isc.apkextract.ResExtrator;

public class MainClass {

	private static boolean helpOption = false;
	private static boolean packageOption = false;
	private static boolean appnameOption = false;
	private static boolean stringOption = false;

	private static String targetPath = "";
	private static List<String> packageFilterStr = new ArrayList<String>(); 
	private static List<String> appFilterStr = new ArrayList<String>(); 
	private static List<String> stringFilterStr = new ArrayList<String>(); 
	
	private static Logger logger = LogManager.getLogger("MainClass");

	public static void main(String[] args) {
		if (args.length <= 1) {
			printOption();
		}
		setTargetPath(args[0]);
		List<String> targetList = null; 
		for (int i = 1; i < args.length; i++) {
			if ("-h".equals(args[i])) {
				setHelpOption(true);
				break;
			}
			else if ("-p".equals(args[i])) {
				targetList = getPackageFilterStr();
				setPackageOption(true);
			}
			else if ("-s".equals(args[i])) {
				targetList = getStringFilterStr();
				setStringOption(true);
			}
			else if ("-n".equals(args[i])) {
				targetList = getAppFilterStr();
				setAppnameOption(true);
			}
			else {
				addTargetFilterList(targetList, args[i]);
			}
		}
		if (helpOption) {
			printOption();
			return;
		}

		List<String>fileList = new ArrayList<String>(); 
		FileAction.CalcalateAllFile(getTargetPath(), fileList);
		//针对每个文件，进行appName、package、string检测；
		logger.warn("共有[" + fileList.size() + "]个应用需要检测......");
		String appList = "";
		if (isAppnameOption() && !getAppFilterStr().isEmpty()) {
			for (int i = 0; i < getAppFilterStr().size(); i++) {
				appList += getAppFilterStr().get(i) + "\t";
			}
		}
		logger.warn("应用名黑名单：" + appList);
		appList = "";
		if (isPackageOption() && !getPackageFilterStr().isEmpty()) {
			for (int i = 0; i < getPackageFilterStr().size(); i++) {
				appList += getPackageFilterStr().get(i) + "\t";
			}
		}
		logger.warn("包名黑名单：" + appList);
		appList = "";
		if (isStringOption() && !getStringFilterStr().isEmpty()) {
			for (int i = 0; i < getStringFilterStr().size(); i++) {
				appList += getStringFilterStr().get(i) + "\t";
			}
		}
		logger.warn("字符串黑名单：" + appList);
		for (int i = 0; i < fileList.size(); i++) {
			logger.info("正在检测: " + fileList.get(i));
			//字符串匹配
			try {
				GetSpecialString.GetStrings(fileList.get(i), getStringFilterStr());
//				****10010***, sth. like this...
//				List<String> CommonList = DexMapItemMapper.getInstance().getresultMap().get("stringList");
//				if (CommonList != null && !CommonList.isEmpty()) {
//					for (int j = 0; j < CommonList.size(); j++) {
//						FilterResult.getInstant().addToStringMap(CommonList.get(j), fileList.get(i));
//					}
//					DexMapItemMapper.getInstance().removeResult("stringList");
//				}
				List<String> speList = DexMapItemMapper.getInstance().getSpecialList();
				if (speList != null && !speList.isEmpty()) {
					for (int j = 0; j < speList.size(); j++) {
						FilterResult.getInstant().addToStringMap(speList.get(j), fileList.get(i));
					}
					DexMapItemMapper.getInstance().removeResult("stringList");
					DexMapItemMapper.getInstance().clearSpecialList();
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
			//包名
			ResExtrator re = new ResExtrator();
			try {
				re.getPackageAndResvalue(fileList.get(i));
			} catch (Exception e) {
				// TODO: handle exception
			}
			String tmpPackageName = re.getPackageNameString();
			for (int j = 0; j < getPackageFilterStr().size(); j++) {
				String currentPackageFileterStr = getPackageFilterStr().get(j);
				//				if (re.getPackageNameString().equals(currentPackageFileterStr)) {
				if (tmpPackageName != null && !"".equals(tmpPackageName) && tmpPackageName.contains(currentPackageFileterStr)) {
					FilterResult.getInstant().addToPackageMap(currentPackageFileterStr, fileList.get(i));
				}
			}
			//文件名
			for (int j = 0; j < getAppFilterStr().size(); j++) {
				String currentAppFilterStr = getAppFilterStr().get(j);
				for (int k = 0; k < re.getResValueStrings().size(); k++) {
					//if (currentAppFilterStr.equals(re.getResValueStrings().get(k))) {
					if (re.getResValueStrings().get(k) != null && !"".equals(re.getResValueStrings().get(k)) && re.getResValueStrings().get(k).contains(currentAppFilterStr)) {
						FilterResult.getInstant().addToAppMap(currentAppFilterStr, fileList.get(i));
						break;
					}
				}
			}
		}
		FilterResult fResult = FilterResult.getInstant();
		fResult.printResult();
		logger.info("FINISHED ! ! !");
	}

	//TODO printOption...
	private static void printOption(){
		System.out.println("ApkfileExtractor targetpath [-p [packageNameFilter ...]] [-s [stringFilter ...]] [-n [appNameFilter ...]]");
	}

	public static boolean isHelpOption() {
		return helpOption;
	}
	public static void setHelpOption(boolean h) {
		helpOption = h;
	}
	public static boolean isPackageOption() {
		return packageOption;
	}
	public static void setPackageOption(boolean p) {
		packageOption = p;
	}
	public static boolean isAppnameOption() {
		return appnameOption;
	}
	public static void setAppnameOption(boolean a) {
		appnameOption = a;
	}
	public static boolean isStringOption() {
		return stringOption;
	}
	public static void setStringOption(boolean s) {
		stringOption = s;
	}
	public static String getTargetPath() {
		return targetPath;
	}
	public static void setTargetPath(String t) {
		targetPath = t;
	}
	public static List<String> getPackageFilterStr() {
		return packageFilterStr;
	}
	public static void addPackageFilterStr(String p) {
		packageFilterStr.add(p);
	}
	public static List<String> getAppFilterStr() {
		return appFilterStr;
	}
	public static void addAppFilterStr(String a) {
		appFilterStr.add(a);
	}
	public static List<String> getStringFilterStr() {
		return stringFilterStr;
	}
	public static void addStringFilterStr(String s) {
		stringFilterStr.add(s);
	}
	public static void addTargetFilterList(List<String> targetList, String str){
		targetList.add(str);
	}
}
